#include "lv_demos/lv_demo.h"
#include "lv_drivers/display/sunxifb.h"
#include "lv_drivers/indev/evdev.h"
#include "lvgl/lvgl.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
lv_obj_t *home_main = NULL;
lv_obj_t *main_page = NULL;

void test_lv_timer_cb(struct _lv_timer_t *timer);

int tplayer_init();
int tplayer_exit();
int tplayer_play(char *url, int x, int y, int width, int height);

void test_lv_event_cb_t(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_SHORT_CLICKED) {
        printf("test_lv_event_cb_t\n");
        tplayer_play("/mnt/UDISK/1.mp4", 100, 100, 150, 150);
    }
}
void test2_lv_event_cb_t(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_SHORT_CLICKED) {
        printf("test_lv_event_cb_t\n");
        tplayer_play("/mnt/UDISK/1.mp4", 100, 100, 200, 200);
    }
}
void test3_lv_event_cb_t(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_SHORT_CLICKED) {
        printf("test_lv_event_cb_t\n");
        tplayer_play("/mnt/UDISK/1.mp4", 100, 100, 250, 250);
    }
}
void test4_lv_event_cb_t(lv_event_t *e) {
    lv_event_code_t code = lv_event_get_code(e);
    if (code == LV_EVENT_SHORT_CLICKED) {
        printf("test_lv_event_cb_t\n");
        tplayer_play("/mnt/UDISK/1.mp4", 100, 100, 300, 300);
    }
}

int main(int argc, char *argv[]) {

    tplayer_init();

    /*LittlevGL init*/
    lv_init();

    uint32_t rotated = LV_DISP_ROT_NONE;

    /*Linux frame buffer device init*/
    sunxifb_init(rotated);

    /*A buffer for LittlevGL to draw the screen's content*/
    static uint32_t width, height;
    sunxifb_get_sizes(&width, &height);

    static lv_color_t *buf;
    buf = (lv_color_t *)sunxifb_alloc(width * height * sizeof(lv_color_t), "lv_examples");

    if (buf == NULL) {
        sunxifb_exit();
        printf("malloc draw buffer fail\n");
        return 0;
    }

    /*Initialize a descriptor for the buffer*/
    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, width * height);

    /*Initialize and register a display driver*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &disp_buf;
    disp_drv.flush_cb = sunxifb_flush;
    disp_drv.hor_res = width;
    disp_drv.ver_res = height;
    disp_drv.rotated = rotated;
    disp_drv.screen_transp = 1;
#ifndef USE_SUNXIFB_G2D_ROTATE
    if (rotated != LV_DISP_ROT_NONE)
        disp_drv.sw_rotate = 1;
#endif
    lv_disp_drv_register(&disp_drv);

    evdev_init();
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER; /*See below.*/
    indev_drv.read_cb = evdev_read;         /*See below.*/
    /*Register the driver in LVGL and save the created input device object*/
    lv_indev_t *evdev_indev = lv_indev_drv_register(&indev_drv);

    home_main = lv_scr_act();

    lv_disp_set_bg_opa(lv_disp_get_default(), LV_OPA_TRANSP);
    lv_memset_00(lv_disp_get_default()->driver->draw_buf->buf_act,
                 lv_disp_get_default()->driver->draw_buf->size * sizeof(lv_color32_t));
    lv_obj_set_style_bg_opa(home_main, LV_OPA_0, 0);

    lv_obj_t *test = lv_obj_create(home_main);
    lv_obj_set_size(test, 480, 480 / 5);
    lv_obj_set_style_border_opa(test, LV_OPA_0, 0);
    lv_obj_set_style_bg_color(test, lv_palette_main(LV_PALETTE_RED), 0);
    lv_obj_set_align(test, LV_ALIGN_TOP_MID);
    lv_obj_add_flag(test, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_event_cb(test, test_lv_event_cb_t, LV_EVENT_ALL, 0);
    lv_obj_t *test2 = lv_obj_create(home_main);
    lv_obj_set_size(test2, 480, 480 / 5);
    lv_obj_set_style_border_opa(test2, LV_OPA_0, 0);
    lv_obj_set_style_bg_color(test2, lv_palette_main(LV_PALETTE_PURPLE), 0);
    lv_obj_set_align(test, LV_ALIGN_BOTTOM_MID);
    lv_obj_add_event_cb(test2, test2_lv_event_cb_t, LV_EVENT_ALL, 0);
    lv_obj_t *test3 = lv_obj_create(home_main);
    lv_obj_set_size(test3, 480 / 5, 480);
    lv_obj_set_style_border_opa(test3, LV_OPA_0, 0);
    lv_obj_set_style_bg_color(test3, lv_palette_main(LV_PALETTE_BLUE), 0);
    lv_obj_set_align(test3, LV_ALIGN_LEFT_MID);
    lv_obj_add_event_cb(test3, test3_lv_event_cb_t, LV_EVENT_ALL, 0);
    lv_obj_t *test4 = lv_obj_create(home_main);
    lv_obj_set_size(test4, 480 / 5, 480);
    lv_obj_set_style_border_opa(test4, LV_OPA_0, 0);
    lv_obj_set_style_bg_color(test4, lv_palette_main(LV_PALETTE_GREEN), 0);
    lv_obj_set_align(test4, LV_ALIGN_RIGHT_MID);
    lv_obj_add_event_cb(test4, test4_lv_event_cb_t, LV_EVENT_ALL, 0);
    /*Handle LitlevGL tasks (tickless mode)*/
    while (1) {
        lv_task_handler();
        usleep(10);
    }
    tplayer_exit();
    /*sunxifb_free((void**) &buf, "lv_examples");*/
    /*sunxifb_exit();*/
    return 0;
}

/*Set in lv_conf.h as `LV_TICK_CUSTOM_SYS_TIME_EXPR`*/
uint32_t custom_tick_get(void) {
    static uint64_t start_ms = 0;
    if (start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}
